package com.mmc.delay.container;

import com.mmc.delay.config.DelayCoreConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.BoundListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.support.ResourceScriptSource;

import java.io.Serializable;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.mmc.delay.constants.RedisKeyConstants.REDIS_READY_QUEUE_KEY;

/**
 * 是一个普通list
 */
public class ReadyQueue implements Serializable {

    private RedisTemplate redisTemplate;

    public ReadyQueue(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    private static final Logger logger = LoggerFactory.getLogger(ReadyQueue.class);


    private BoundListOperations getQueue () {
        return redisTemplate.boundListOps(REDIS_READY_QUEUE_KEY);
    }

    /**
     * 移除并获得任务
     * @return
     */
    public List<String> popJob() {
        Integer readyQueueBatchSize = DelayCoreConfig.getReadyQueueBatchSize();
        DefaultRedisScript<List> redisScript =new DefaultRedisScript<>();
        redisScript.setResultType(List.class);
        redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/lrangAndLTrim.lua")));
        List<String> jobIds = null;
        try {
            jobIds = (List) redisTemplate.execute(redisScript,Collections.singletonList(REDIS_READY_QUEUE_KEY),readyQueueBatchSize);
        }catch (Exception e){
           logger.error("lrangAndLTrim lua error",e);
        }
        //没有数据的话，用leftPop方法阻塞线程
        if(jobIds==null||jobIds.isEmpty()){
            Object jobIdObj = null;
            try {
                jobIdObj = getQueue().leftPop(DelayCoreConfig.getReadyNotMessageWaitTime(),TimeUnit.MILLISECONDS);
            } catch (Exception e) {
            }
            if(jobIdObj!=null){
                jobIds.add(jobIdObj.toString());
            }
        }
        return jobIds;
    }

    public void addReadQueue(String jobId) {
        logger.info("任务移入Reday List,jobId:{}",jobId);
        getQueue().rightPush(jobId);
    }


    
}
